package com.hx.vending.util;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.UploadFileRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.mts.model.v20140618.*;
import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse.JobResult;
import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse.JobResult.Job;
import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse.JobResult.Job.Output;
import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse.JobResult.Job.Output.OutputFile;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoRequest;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;
import java.util.zip.ZipOutputStream;

public class AliyunOSSClientUtil {

    //阿里云API的密钥Access Key ID
    @Value("${aliyun.oss.accessKeyId}")
    private static String accessKeyId;
    //阿里云API的密钥Access Key Secret
    @Value("${aliyun.oss.accessKeySecret}")
    private static String accessKeySecret;
    // 阿里云链接地址
    @Value("${aliyun.oss.path}")
    private static String path;
    //阿里云API的bucket名称
    @Value("${aliyun.oss.bucketName}")
    private static String bucketName;
    //阿里云API的内或外网域名
    @Value("${aliyun.oss.endpoint}")
    private static String endpoint;

    // 获取logger实例
    protected static Logger logger = Logger.getLogger(AliyunOSSClientUtil.class);
    
    static{
    	//获取properties中的值
        Resource resource = new ClassPathResource("OSSBucket.properties");
        Properties props=null;
        try {
		    props = PropertiesLoaderUtils.loadProperties(resource);
		    endpoint=props.getProperty("aliyun.oss.endpoint");
		    accessKeyId=props.getProperty("aliyun.oss.accessKeyId");
		    accessKeySecret=props.getProperty("aliyun.oss.accessKeySecret");
		    bucketName=props.getProperty("aliyun.oss.bucketName");
		    path=props.getProperty("aliyun.oss.path");
	    } catch (IOException e1) {
		    // TODO Auto-generated catch block
		    e1.printStackTrace();
	    }
    }




    /**
     * 上传图片至OSS
     * @param file 上传文件(改为使用流上传)
     * @param fileName 文件名  时间戳+随机四位字母（大小写）.jpg
     * @param folder 模拟文件夹名 如"qj_nanjing/"
     * @param fileSize 文件大小
     * @param imgIs 输入流
     * @return String 返回的唯一MD5数字签名
     * */
    public static String uploadObjectToOSS(File file, String fileName, String folder,Long fileSize,InputStream imgIs){

        String resultStr = null;
        try {
            //以输入流的形式上传文件
            //InputStream imgIs = new FileInputStream(file);       

            //文件大小
            //Long fileSize = file.length();
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(imgIs.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
            // 如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(getContentType(fileName));
            //指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            // 获取阿里云OSS客户端对象
            OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
            //上传文件   (上传文件流的形式)
            PutObjectResult putResult = ossClient.putObject(bucketName, folder + fileName, imgIs, metadata);
            //图片路径
            resultStr = path+'/'+folder+fileName;
            // 关闭OSSClient
            ossClient.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
            //System.out.println("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return resultStr;
    }

    /**
     * 删除阿里云上面的图片
     * @param fileName
     */
    public static void deleteObject(String fileName) {
        // 创建OSSClient实例
        //根据com/切割来删除文件夹下的文件名，暂未实现根据全路径删除功能
        //String str = "http://douya-welding.oss-cn-shenzhen.aliyuncs.com/User/20180102023504138-31.jpg";
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        if (fileName.contains(".com/")) {
        	ossClient.deleteObject(bucketName, fileName.split(".com/")[1]);
		}
        ossClient.shutdown();
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     * @param fileName 文件名
     * @return 文件的contentType
     * */
    public static  String getContentType(String fileName){
        //文件的后缀名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if(".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if(".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if(".jpeg".equalsIgnoreCase(fileExtension) ) {
            return "image/jpeg";
        }
        if(".jpg".equalsIgnoreCase(fileExtension)){
            return "image/jpg";
        }
        if(".png".equalsIgnoreCase(fileExtension)){
            return "image/png";
        }
        if(".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if(".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if(".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if(".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if(".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if(".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        if(".pdf".equalsIgnoreCase(fileExtension)) {
            return "application/pdf";
        }
        //默认返回类型
        return "image/jpeg";
    }

    /**
     * 处理上传的图片文件
     * @param file MultipartFile类型的文件
     * @param folder 要上传的文件夹  (upload/)
     * @return
     */
    public static String handleUploadFile(MultipartFile file,String folder){
    	String val="";
    	String filename="";
    	//获取文件的格式（图片格式）
        String extention = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
		Random random=new Random();
		for(int i=0;i<4;i++){
			int temp=random.nextInt(2)%2==0?65:97;
			val+=(char)(random.nextInt(26)+temp);
		}
		//修改文件名：时间戳+随机四位字母
		filename=new Date().getTime()+val+"."+extention;
		//将MultipartFile类型转换为File类型
        File newfile=null;
        InputStream ins = null;
		try {
			ins = file.getInputStream();
		    newfile=new File(file.getOriginalFilename());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//上传文件并获取文件最终的路径
		String imgurl=uploadObjectToOSS(newfile, filename, folder,file.getSize(),ins);
		return imgurl;
    }
    
    
    /**
     * 处理上传的pdf文件
     * @param file MultipartFile类型的文件
     * @param folder 要上传的文件夹  (upload/)
     * @return
     */
    public static String handleUploadFilePDF(MultipartFile file,String folder){
    	String val="";
    	String filename="";
    	//获取文件的格式
        String extention = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
//		Random random=new Random();
//		for(int i=0;i<4;i++){
//			int temp=random.nextInt(2)%2==0?65:97;
//			val+=(char)(random.nextInt(26)+temp);
//		}
//		//修改文件名：时间戳+随机四位字母
//		filename=new Date().getTime()+val+"."+extention;
        filename=file.getOriginalFilename();
		//将MultipartFile类型转换为File类型
        File newfile=null;
        InputStream ins = null;
		try {
			ins = file.getInputStream();
		    newfile=new File(file.getOriginalFilename());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//上传文件并获取文件最终的路径
		String imgurl=uploadObjectToOSS(newfile, filename, folder,file.getSize(),ins);
		return imgurl;
    }
    /**
     * 上传视频
     */
    public static String handleUploadVideo(byte[] b,String folder){
        // 获取阿里云OSS客户端对象
        OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
        // 以输入流的形式上传文件
        /*String folder = "";*/
        /*folder = folder + "/" + DateUtil.getDays() + "/";*/
        // 文件名
        String timefile = DateUtil.getAllTime();// 文件名
        String fileName = ".MP4";// 后缀扩展名
        fileName = timefile + fileName;
        logger.info("上传到路径" + folder + fileName);
        Long fileSize = (long) b.length;
        // 创建上传Object的Metadata
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(fileSize);
        // 指定该Object被下载时的网页的缓存行为
        metadata.setCacheControl("no-cache");
        // 指定该Object下设置Header
        metadata.setHeader("Pragma", "no-cache");
        // 指定该Object被下载时的内容编码格式
        metadata.setContentEncoding("utf-8");
        // 文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
        // 如果没有扩展名则填默认值application/octet-stream
        metadata.setContentType(getContentType(fileName));
        // 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
        metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
        PutObjectResult putResult = ossClient.putObject(bucketName, folder + fileName, new ByteArrayInputStream(b),metadata);
        String filepath = folder + fileName;
        ossClient.shutdown();
        return filepath;
    }

    public String uploadVideo(String fileurl,String templateId)throws Throwable {
        String timefile = DateUtil.getAllTime();// 文件名
        String fileName = ".MP4";// 后缀扩展名
        fileName = timefile + fileName;
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 设置断点续传请求
        UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, fileName);
        // 指定上传的本地文件
        uploadFileRequest.setUploadFile(fileurl);
        // 指定上传并发线程数
        uploadFileRequest.setTaskNum(5);
        // 指定上传的分片大小
        uploadFileRequest.setPartSize(1 * 1024 * 1024);
        // 开启断点续传
        uploadFileRequest.setEnableCheckpoint(true);
        System.out.println("开始上传视频.....");
        // 断点续传上传
        ossClient.uploadFile(uploadFileRequest);
        System.out.println("上传成功！");
        System.out.println("开始转码...");
        String url= transcoding(bucketName,fileName, accessKeyId, accessKeySecret);
        //System.out.println("转码后播放地址："+url);
        //删除指定对象
        ossClient.deleteObject(bucketName, fileName);
        // 关闭client
        ossClient.shutdown();
        return url;
    }
    public static String transcoding(String bucketName,String fileName,String accessKeyId,String accessKeySecret)throws ClientException{
        String url = "";
        String location = "oss-cn-beijing";
        DefaultProfile.addEndpoint("cn-beijing",
                "cn-beijing",
                "Mts",
                "mts.cn-beijing.aliyuncs.com");
        IClientProfile profile = DefaultProfile.getProfile(location.substring(4), accessKeyId, accessKeySecret);
        IAcsClient client=new DefaultAcsClient(profile);
        String templateId = "112ae708b1a14cf0bcbd62e75c9210f0";
      /*  //模板
        SearchTemplateRequest templateRequest = new SearchTemplateRequest();
        //templateRequest.set
        SearchTemplateResponse templateResponse = client.getAcsResponse(templateRequest);
        String templateId = templateResponse.getTemplateList().get(0).getId();
        System.out.println("===============模板id"+templateId);*/
        //开始转码
        SubmitJobsRequest submitjobs=new SubmitJobsRequest();
        String input="{\"Bucket\":\""+bucketName+"\",\"Location\":\""+location+"\",\"Object\":\""+fileName+"\"}";
        String outputs="[{\"OutputObject\":\""+fileName+"\",\"TemplateId\":\""+templateId+"\"}]";
        String outputbucket=bucketName;
        String OutputLocation=location;

        submitjobs.setOutputLocation(OutputLocation);
        submitjobs.setInput(input);
        submitjobs.setOutputs(outputs);
        submitjobs.setOutputBucket(outputbucket);

        try{
            //获取管道
            SearchPipelineRequest searchPipeline=new SearchPipelineRequest();
            SearchPipelineResponse sarchPipelineResponse=client.getAcsResponse(searchPipeline);
            String pipelineid=sarchPipelineResponse.getPipelineList().get(0).getId();

            System.out.println("管道id===================="+pipelineid);
            //给管道赋值
            submitjobs.setPipelineId(pipelineid);
            SubmitJobsResponse response=client.getAcsResponse(submitjobs);
            List<JobResult> list= response.getJobResultList();
            JobResult jobResult=list.get(0);
            Job job=jobResult.getJob();
            Output output=job.getOutput();
            OutputFile outputfile=output.getOutputFile();
            url="http://"+outputfile.getBucket()+"."+outputfile.getLocation()+".aliyuncs.com/"+outputfile.getObject();
            String jobid=job.getJobId();
            System.out.println("转码任务id="+jobid);
            QueryJobListRequest queryjoblist=new QueryJobListRequest();
            queryjoblist.setJobIds(jobid);
            for(int i=0;i<2;i=0){
                QueryJobListResponse queryresponse=client.getAcsResponse(queryjoblist);
                String state=queryresponse.getJobList().get(0).getState();

                if(state.equals("Transcoding")||state.equals("Submitted")){
                    //AliyunOSSClientUtil.deleteVideo(previoueUrl);
                    Thread thread = Thread.currentThread();
                    thread.sleep(5000);//暂停5秒后程序继续执行
                }else if(state.equals("TranscodeFail")||state.equals("TranscodeCancelled")){
                    AliyunOSSClientUtil.deleteVideo(url);
                    url="";
                }else {
                    //AliyunOSSClientUtil.deleteVideo(previoueUrl);
                    break;
                }
            }
        }catch(Exception e){
            AliyunOSSClientUtil.deleteVideo(url);
            System.out.println("视频转码错误码-----"+e.getMessage());
            e.printStackTrace();
            url = "";
        }
        return url;
    }

    /**
     * 上传模板
     * @param name 模板名称
     * @param container 模板容器
     * @param video 视频流配置
     * @param audio 音频流配置
     * @param //transConfig 转码通用配置
     * @param //muxConfig 封包配置
     * @return
     * @throws ClientException
     */
    public static String addTemplate(String name,String container,String video,String audio)throws ClientException{
        String templateId = "";
        String location = "oss-cn-beijing";
        DefaultProfile.addEndpoint("cn-beijing",
                "cn-beijing",
                "Mts",
                "mts.cn-beijing.aliyuncs.com");
        AddTemplateRequest template=new AddTemplateRequest();
        template.setName(name);
        if(!container.equals("")){
            template.setContainer(container);
        }
        if(!video.equals("")){
            template.setVideo(video);
        }
        if(!audio.equals("")) {
            template.setAudio(audio);
        }
        //创建IClientProfile
        IClientProfile profile=DefaultProfile.getProfile(location.substring(4), accessKeyId, accessKeySecret);
        IAcsClient client=new DefaultAcsClient(profile);
        try{
            AddTemplateResponse templateResponse=client.getAcsResponse(template);
            templateId=templateResponse.getTemplate().getId();
        }catch (Exception e){
            e.printStackTrace();
        }
        return templateId;
    }

    /**
     * 删除模板
     * @param template_id
     * @throws ClientException
     */
     public static String deleteTemplate(String template_id)throws ClientException{
         String templateId = "";
         String location = "oss-cn-beijing";
         DefaultProfile.addEndpoint("cn-beijing",
                 "cn-beijing",
                 "Mts",
                 "mts.cn-beijing.aliyuncs.com");
         DeleteTemplateRequest deleterequest=new DeleteTemplateRequest();
         deleterequest.setTemplateId(template_id);
         //创建IClientProfile
         IClientProfile profile=DefaultProfile.getProfile(location.substring(4), accessKeyId, accessKeySecret);
         IAcsClient client=new DefaultAcsClient(profile);
         try{
             templateId = client.getAcsResponse(deleterequest).getTemplateId();
         }catch (Exception e){
             e.printStackTrace();
         }
         return templateId;
     }

    /**
     * 删除视频
     * @param url 视频播放地址
     */
    public static void deleteVideo(String url){
        int index=url.lastIndexOf("/");
        index=url.lastIndexOf("/", index-1);
        String filename=url.substring(index+1);

        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        ossClient.deleteObject(bucketName, filename);
        // 关闭client
        ossClient.shutdown();
        //return null;
    }
    //直接使用MultipartFile上传到阿里云服务器  返回转码后的url
    public static String getOSSUrl(MultipartFile file) throws Exception{
        //endpoint = "https://oss-cn-beijing-internal.aliyuncs.com";
        String timefile = DateUtil.getAllTime();// 文件名
        System.out.println("timefile================"+timefile);
        String fileName = ".MP4";// 后缀扩展名
        fileName = timefile + fileName;
        String folder = "video/";
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        InputStream inputStream = file.getInputStream();
        //BufferedInputStream bis = new BufferedInputStream ( inputStream );
        //FileOutputStream outputStream = new FileOutputStream((File) file);
        //ZipOutputStream zos = new ZipOutputStream(outputStream);
        //BufferedOutputStream bos = new BufferedOutputStream (zos);
        ossClient.putObject(bucketName, folder+ fileName, inputStream);

//        String url ="";
//        try {
//            url = AliyunOSSClientUtil.transcoding(bucketName,folder + fileName,accessKeyId, accessKeySecret);
//        } catch (ClientException e) {
//            url = "";
//            System.out.println("错误码为====="+e.getErrCode());
//            e.printStackTrace();
//        }
        String url ="http://shouhuojixiangmu.oss-cn-beijing.aliyuncs.com/"+folder+fileName;


        return  url;
    }

    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) {
        //点播服务所在的Region，国内请填cn-shanghai，不要填写别的区域
        String regionId = "cn-shanghai";
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }


}